"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具显示磁盘信息，指定输出信息的文件类型
Create At   : 2023/4/21
Owner       : opentestcase019
Description :
    1.显示磁盘信息，查看帮助信息
    2.显示磁盘信息，不指定参数
    3.显示磁盘信息，指定-g vg_name和-s struct_name参数为有效值
    4.显示磁盘信息，指定-g vg_name参数为无效值
    5.显示磁盘信息，指定-s struct_name参数为无效值
    6.在dss关闭的情况下执行显示磁盘信息
    7.在集群停止的情况下执行
    8.DSS_HOME路径权限不足时，显示磁盘信息，不指定-D DSS_HOME参数
    9.在备机显示磁盘信息
    10.显示磁盘信息，指定-D DSS_HOME参数为正常值
    11.显示磁盘信息，指定指定错误的-D DSS_HOME参数和权限不足的socket_domain
Expect      :
    1.查看成功
    2.合理报错
    3.显示成功
    4.合理报错
    5.合理报错
    6.显示成功
    7.显示成功
    8.合理报错
    9.显示成功
    10.显示成功
    11.合理报错
History     :
"""
import os
import time
import re
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.logger.info("-----获取卷组名-----")
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("Succeed to display lsvg info.", execute_msg, "获取卷组名失败")
        self.vg_1 = execute_msg.splitlines()[1].split()[0].strip()
        self.vg_2 = execute_msg.splitlines()[2].split()[0].strip()
        self.vg_64chars = \
            'vg_name_0040_vg_name_0040_vg_name_0040_vg_name_0040_vg_n_64chars'

    def test_sharestorage_tool(self):
        step1 = "-----step1:显示磁盘信息，查看帮助信息;expect:查看成功-----"
        self.logger.info(step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd showdisk -h"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('Usage:dsscmd showdisk <-g vg_name> <-s struct_name> '
                      '[-D DSS_HOME]\n      dsscmd showdisk <-g vg_name> '
                      '<-b block_id> <-n node_id> [-D DSS_HOME]\n'
                      '[client command] show disk information\n-g/--vg_name '
                      '<vg_name>, <required>, the volume group name\n'
                      '-s/--struct_name <struct_name>, <required>, the struct '
                      'name of volume group, the optional value(s):\n    '
                      '[core_ctrl | vg_header | volume_ctrl | root_ft_block]\n'
                      '-b/--block_id <block_id>, <required>, fs block id or '
                      'ft block id\n-n/--node_id <node_id>, <required>, node '
                      'id in block\n-D/--DSS_HOME <DSS_HOME>, [optional], the '
                      'run path of dssserver, default value is $DSS_HOME',
                      execute_msg, "执行失败" + step1)

        step2 = "-----step2:显示磁盘信息，查看帮助信息;expect:查看成功-----"
        self.logger.info(step2)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd showdisk;"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('should set the vg name to show.',
                      execute_msg, "执行失败" + step2)

        step3 = "-----step3:显示磁盘信息，指定-g vg_name和-s struct_name参数" \
                "为有效值;expect:显示成功-----"
        self.logger.info(step3)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd showdisk -g {self.vg_1} -s core_ctrl;
            dsscmd showdisk --vg_name {self.vg_1} --struct_name vg_header;
            dsscmd showdisk -g {self.vg_2} -s volume_ctrl;
            dsscmd showdisk --vg_name {self.vg_2} --struct_name root_ft_block'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(4, execute_msg.count(
            "Succeed to printf dss metadata"), "执行失败" + step3)

        step4 = "-----step4:显示磁盘信息，指定-g vg_name参数为无效值;expect:合理报错-----"
        self.logger.info(step4)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd showdisk -g {self.vg_1}卷组 -s core_ctrl;" \
            f"dsscmd showdisk --vg_name {self.vg_1}_not_exists " \
            f"--struct_name vg_header;" \
            f"dsscmd showdisk -g {self.vg_1}@#% -s volume_ctrl;" \
            f"dsscmd showdisk -g {self.vg_64chars} -s volume_ctrl"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f'Path {self.vg_1}卷组 decode error , name should be '
                      f'[0~9,a~z,A~Z,-,_,.]', execute_msg, "执行失败" + step4)
        self.assertIn('Failed to get vg data_not_exists.',
                      execute_msg, "执行失败" + step4)
        self.assertIn(f'Path {self.vg_1}@#% decode error , name should be '
                      f'[0~9,a~z,A~Z,-,_,.]', execute_msg, "执行失败" + step4)
        self.assertIn(f'Path {self.vg_64chars} decode error , '
                      f'name is too long', execute_msg, "执行失败" + step4)

        step5 = "-----step5:显示磁盘信息，指定-s struct_name参数为无效值;expect:合理报错-----"
        self.logger.info(step5)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd showdisk -g {self.vg_1} -s core_ctrl_not;
            dsscmd showdisk --vg_name {self.vg_1} --struct_name 111;
            dsscmd showdisk -g {self.vg_1} -s core_ctrl_不;
            dsscmd showdisk --vg_name {self.vg_1} --struct_name core_ctrl@#^*&
            '''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(4, execute_msg.count("Incorrect struct_name input."),
                          "执行失败" + step5)

        step6 = "-----step6:在dss关闭的情况下执行显示磁盘信息;expect:显示成功-----"
        self.logger.info(step6)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd stopdss;
            dsscmd showdisk -g {self.vg_1} -s vg_header;
            dsscmd showdisk --vg_name {self.vg_1} --struct_name volume_ctrl'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn('Succeed to stop server.', execute_msg, "执行失败" + step4)
        self.assertEquals(2, execute_msg.count(
            "Succeed to printf dss metadata."), "执行失败" + step6)

        step7 = "-----step7:在集群停止的情况下执行;expect:显示成功-----"
        self.logger.info(step7)
        stop_msg = self.primary_sh.exec_cm_ctl(mode='stop')
        self.logger.info(stop_msg)
        self.assertIn(self.constant.cm_stop_success_msg,
                      stop_msg, '执行失败' + step6)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
        dsscmd showdisk -g {self.vg_1} -s vg_header;
        dsscmd showdisk --vg_name {self.vg_1} --struct_name volume_ctrl'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, execute_msg.count(
            "Succeed to printf dss metadata."), "执行失败" + step6)
        start_msg = self.primary_sh.exec_cm_ctl(mode='start')
        self.logger.info(start_msg)
        self.assertIn(self.constant.cm_start_success_msg, start_msg, '启动集群失败')
        time.sleep(30)
        status = self.primary_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败')

        step8 = "-----step8:DSS_HOME路径权限不足时，显示磁盘信息，" \
                "不指定-D DSS_HOME参数;expect:合理报错-----"
        self.logger.info(step8)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            chmod 000 {macro.DSS_INSTANCE};
            dsscmd showdisk -g {self.vg_1} -s vg_header;
            dsscmd showdisk --vg_name {self.vg_1} --struct_name volume_ctrl;
            chmod 700 {macro.DSS_INSTANCE};'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, execute_msg.count(
            "dss_inst.ini does not exist"), "执行失败" + step8)

        step9 = "-----step9:在备机显示磁盘信息;expect:显示成功-----"
        self.logger.info(step9)
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            dsscmd showdisk -g data -s vg_header;
            dsscmd showdisk --vg_name data --struct_name volume_ctrl;'''
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertEquals(2, execute_msg.count(
            "Succeed to printf dss metadata."), "执行失败" + step9)

        step10 = "-----step10:显示磁盘信息，指定-D DSS_HOME参数为正常值;expect:显示成功-----"
        self.logger.info(step10)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd showdisk -g data -s vg_header -D {macro.DSS_INSTANCE}; " \
            f"dsscmd showdisk --vg_name {self.vg_1} --struct_name " \
            f"volume_ctrl -D {macro.DSS_INSTANCE};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(2, execute_msg.count(
            "Succeed to printf dss metadata."), "执行失败" + step10)

        step11 = "-----step11:显示磁盘信息，指定指定错误的-D DSS_HOME参数" \
                 "和权限不足的socket_domain;expect:合理报错-----"
        self.logger.info(step11)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd showdisk -g {self.vg_1} -s vg_header " \
            f"-D {macro.DSS_INSTANCE}_error;" \
            f"dsscmd showdisk --vg_name {self.vg_1} --struct_name " \
            f"volume_ctrl -D {macro.DSS_INSTANCE}_error;" \
            f"chmod 000 {macro.DSS_INSTANCE};" \
            f"dsscmd showdisk -g data -s vg_header -D {macro.DSS_INSTANCE};" \
            f"dsscmd showdisk --vg_name data --struct_name volume_ctrl " \
            f"-D {macro.DSS_INSTANCE};" \
            f"chmod 700 {macro.DSS_INSTANCE};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertEquals(4, execute_msg.count(
            "Failed to load config info!"), "执行失败" + step10)
        self.assertEquals(4, execute_msg.count(
            "dss_inst.ini does not exist"), "执行失败" + step10)

    def tearDown(self):
        self.logger.info("-----无需清理环境-----")
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
